function varargout = rslice(varargin)
% RSLICE:  ROMS slicing tool
%
%      RSLICE, by itself, creates a new RSLICE or raises the existing
%      singleton*.
%
%      H = RSLICE returns the handle to a new RSLICE or the handle to
%      the existing singleton*.
%
%      RSLICE('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in RSLICE.M with the given input arguments.
%
%      RSLICE('Property','Value',...) creates a new RSLICE or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before rslice_OpeningFunction gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to rslice_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See the doc directory for more information.
%
% See also: GUIDE, GUIDATA, GUIHANDLES
%
% CALLS:
%     rslice_hslice_redraw, rslice_initialize
% CALLED BY:
%     Nothing
%

%
% Fields of the global data structure, sometimes called "gdata", 
% sometimes called "rslice_object", sometimes called "rslice_data".
%
%     default_depth:
%         Depth (positive downward) in meters at which to take the 
%         first horizontal slice.
%     dim_type:
%         One of these possibilities.
%             'YX':  no vertical or temporal dimension.  Like 'h'.
%             'TYX':  no vertical dimension, like 'u_bar'.
%             'TZYX':  a full four dimensional dataset, like 'temp'.
%     hslice_on_sigma:
%         A flag.  If set, then the current variable should be sliced
%         along the sigma coordinate (much faster) than the other
%         case, which is slicing along a constant depth.
%     first_redraw:
%         There are a few things that are done differently if we've
%         already rendered a slice once, so we keep track of this 
%         thru a flag.  One of these things is setting the CLim 
%         property for the first rendering.
%     input_type:
%         Can be either 'file', 'directory', 'url'
%         'file' and 'directory' mean that the data is being retrieved
%         from files on the local filesystem.  'url' means that an
%         opendap server is the data source.  
%     interpolation_method:
%         Can be one of 
%             'griddata_lite':  
%                 A variation on the griddata algorithm.
%             'nearest':  
%                 Nearest neighbor
%         This controls how the slice values are interpolated from
%         the dataset.
%     load_time_series_variables_only:
%         If set, then such variables as "h", "lon_rho", etc. will not
%         be included in the list of variables to choose from.
%     max_num_timesteps:
%         The number of discrete time steps available for perusal in 
%         the current dataset.  This value is echoed in the rslice 
%         figure window.
%     max_num_usable_vars:
%         If there are so many variables in the dataset, then using
%         a drop down menu becomes a bad way to do it, and we should
%         use a dialog box instead.
%     ncfile_index:
%         A 1-based index into "ncfile_list".
%     ncfile_list:
%         A cell array.
%
%         switch ( input_type )
%         case 'directory'
%             Could be many values, possibly as many as there are files
%             within the intended directory.
%         case 'file'
%             Just one value, the full pathname of a single NetCDF 
%             file.
%         case 'url'
%             Just one value, the URL of the opendap dataset.
%         end
%
%     ncfile_start_index, ncfile_stop_index:
%         An array whose size is the same as ncfile_list, so only in
%         the case of 'directory' is it anything other than a single
%         value, which would be 0.  In the case of 'directory', then
%         each element corresponds to a netcdf file, specifically
%         where the first and last time step in that file fall into 
%         place in the aggregated time series.  For example, suppose 
%         that there are three netcdf files in the current directory.
%         File A has 5 timesteps, file B has 7 timesteps, and file C
%         has 9 timestep.  Then the values of the ncfile_start_index
%         would be [0 5 12] and the value of the ncfile_stop_index
%         would be [4 11 20].
%
%     ocean_time:
%         Vector of all time values from all netcdf input files.
%         The units are matlab datenum, however, not julian days or 
%         "seconds since yyyy-mm-dd" or whatever it was that is 
%         present in the "units" attribute of the "ocean_time" variable.
%
%     record_variable:
%         Specify this in case the unlimited record variable is not 
%         'ocean_time'.  So the default record variable is 'ocean_time'.
%
%     restricted_varlist:
%         If present, then this is a user-specified list of variables.
%         Sometimes there are so many roms variables that it overwhelms
%         the GUI.  This is a way to ease it a bit.
%
%     rslice_grid:
%         A structure with five subfields.  These subfields are
%       
%         coordsys:
%             Either 'geographic' (if the input files have lat_rho
%             and lon_rho) or 'xy' otherwise (x_rho and y_rho).
%         roms_grid:
%             Structure as returned by m-file "roms_get_grid.m"
%         x, y:
%             Structures with metadata about the horizontal and 
%             vertical coordinates referenced by coordsys above.
%         angle:
%             Structure with metadata about the ROMS variable "angle".
%             If the coordsys is 'xy', then this is ignored.
%     sigma_index:
%         If slicing along the sigma coordinate, this index specifies
%         the index of the sigma coordinate.  The default is 0.  It
%         can be changed to xxx by typing "s=xxx" in the depth edit
%         box.
%     timestep:
%         The current time index.
%     varinfo:
%         A structure of information about the current variable.
%     varlist:
%         Cell array of usable variables.
%     varname:
%         The name of the dataset currently being displayed in the 
%         rslice figure window.
%     velocity:
%         A structure with two fields, 'u_velocity' and 'v_velocity'.
%         Each of these fields is in turn a structure of metadata about
%         their respective velocity dataset.
%     verbose:
%         This is a flag that can be set from the command line.  If
%         set to 1, then rslice will print out a bit more information
%         during its course of operation than otherwise.  It currently
%         is not well implemented, though.
%     vslice_data:
%         A matlab structure that is only present when a vertical slice
%         has been defined.  This structure has five fields.
%             vx, vz: 
%                 Arrays that define the horizontal and vertical 
%                 directions (vertical meaning down) along the vertical
%                 slice. 
%             vdata:
%                 Data from vertical slice variable at the locations
%                 defined by vx, vz.
%             control_pt_x, control_pt_y:
%                 Control points that defined the slice.  
%     z_type:
%         Either 's_rho' or 's_w', which are names of the sigma depth
%         coordinates.  's_w' is typically one more than 's_r'.  It
%         affects how the depths are calculated.
%
% GUI Controls    
%     close_menu:
%         A menu item under "File".  This closes out the current rslice
%         object.
%     default_depth:
%         If no depth is provided, then this is the depth we assume to
%         slice at.
%     depth_edit:
%         An editable text widget that controls either the depth or the
%         sigma coordinate at which the current data set is sliced. 
%         The default is sigma coordiate, which is designated with an
%         "s=" string prepended onto the numeric value.  Getting rid
%         of the prefix makes rslice interpret the value as a depth.
%     fastforward_pushbutton:
%         A pushbutton which will start an animation by continually 
%         advancing the time step until the end is reached.
%     file_menu:
%         A drop down menu that exposes the usual File options one
%         would expect in a File menu, such as open and close.
%     hslice_figure:
%         This is the same as the rslice field.  Don't use 
%         "hslice_figure".
%     horizontal_slice_axis:
%         This is the main axis that displays during rslice operations.
%     horizontal_slice_title:
%         Lost in space?
%     horizontal_slice_title2:
%         A bad name for a title string on the main rslice window.
%     horizontal_cmax_edit:
%         An editable text widget that displays the current maximum 
%         value of the rslice window color range.  This can be changed
%         manually, or by changing variables.
%     horizontal_cmin_edit:
%         An editable text widget that displays the current minimum 
%         value of the rslice window color range.  This can be changed
%         manually, or by changing variables.
%     horizontal_cmax_text:
%         A read-only text widget that just displays "CMax".  It refers
%         to the maximum value of the color range.
%     horizontal_cmn_text:
%         A read-only text widget that just displays "CMin".  It refers
%         to the minimal value of the color range.
%     hvoc_figure:
%         A handle for the horizontal velocity overlay control window.
%     max_sigma_level:
%         Number of sigma coordinates possible in the current variable.
%         For something like 'h', this is 0.
%     new_directory:
%         A menu item under the "File" menu.  A native matlab directory
%         browser window pops up, allowing the user to navigate to 
%         another directory source of ROMS files.
%     new_menu:
%         A menu item under the "File" menu.  A native matlab file
%         browser window pops up, allowing the user to navigate to a 
%         new ROMS file.
%     new_url_menu:
%         A menu item under the "File" menu.  A crude popup appears
%         that allows the user to type in a new URL to load.  Did I
%         say that it was crude?
%     original_xlim, original_ylim:
%         These are the original XLim and YLim properties of the first
%         rendering of a dataset.  They are used for "zoom back".
%     other_menu:
%         Drop down menu that contains other miscellaneous menu items.
%         Maybe "Miscellaneous" would have been a better name.
%     output:
%         Currently this is the same as the rslice field.  Don't use
%         this.
%     rslice:
%         This is the return parameter for the rslice m-file.  Thru 
%         this handle, all of the other gui widgets and fields can
%         be accessed.
%     rewind_pushbutton:
%         A pushbutton on the main rslice figure window which will 
%         start an animation by continually advancing the time step
%         BACKWARDS by one discrete unit until the beginning is 
%         reached.
%     sigma_index:
%         An index into the sigma layer coordinate.  0 is the bottom
%         layer in roms.
%     step_back_pushbutton:
%         A pushbutton which will advance the current time BACKWARDS by
%         one discrete time step.
%     step_forward_pushbutton:
%         A pushbutton which will advance the current time by one 
%         discrete time step.
%     stop_animation_button:
%         A pushbutton whose only job is to toggle a flag.  If this
%         is done during the middle of an animation (such as the
%         time step continually advancing), then the animation
%         will be broken.
%     timestep_edit:
%         An editable text widget that displays the current time index
%         (not time value) of the ROMS dataset.  It is zero-based.
%     timestep_text:
%         A text widget that displays the value of the current time 
%         step in human readable terms.
%     variable_menu:
%         A drop down menu that exposes the list of ROMS variables that
%         the user can choose to display.
%     velocity_overlay_tag:
%         A menu item under "Other".  This initiates a popup figure
%         window that the user will control to specify how the 
%         velocity overlay arrows will look.
%     vslice_figure:
%         A handle for the vertical slice figure window.
%     vslice_menu:
%         A menu item under "Other".  This initiates a vertical slice
%         operation on the dataset being currently displayed in the
%         rslice figure window.
%     vslice_vel_figure:
%         A handle for the vertical slice velocity figure window.
%     vslice_velocity_menu:
%         A menu item under "Other".  This initiates a vertical slice
%         operation on the vertical velocity fields, regardless of
%         what the current dataset it.  If there are no velocity 
%         fields, then this menu item is grayed out.
%     zoom_back_menu:
%         A menu item under "Other".  This "unzooms" by bringing the
%         field of view back to the original state.
%     zoom_menu:
%         A menu item under "Other".  This enables the usual zooming
%         feature, which is normally turned off.
%         
%

% Edit the above text to modify the response to help rslice
% Last Modified by GUIDE v2.5 11-May-2006 08:10:33
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @rslice_OpeningFcn, ...
                   'gui_OutputFcn',  @rslice_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);



if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT



return




% --- Executes just before rslice is made visible.
function rslice_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to rslice (see VARARGIN)

% Choose default command line output for rslice
handles.output = hObject;

% Update handles structure
%guidata(hObject, handles);

gdata = guidata ( hObject );
gdata.output = hObject;
gdata.rslice = hObject;
guidata ( hObject, gdata );


% UIWAIT makes rslice wait for user response (see UIRESUME)
% uiwait(handles.hslice_figure);
options = rslice_defaults;

%
% Parse the user-supplied command line inputs.  Store them
% in a structure called "options".
%
% Fields of options structure:
%     input_type:
%         One of four possibilities.
%           'directory' :  
%               Use a collection of NetCDF files all in the same 
%               directory.
%           'file' :
%               Use a single NetCDF file.
%           'url' :
%               Use an OpenDAP dataset.  Works the same as a file, but
%               The user MUST have an opendap-enabled mexnc available.
%     regex:
%           Regular expression to be used to par down the list of
%           files to be used when the input_type is 'directory'
%     source:
%           If the input type is 'file', then this is the file (duh)
%           the user wants to be used.
%           If the input type is 'url', then this is the url (duh)
%           the user wants to be used.
%           If the input type is 'directory', then this is the directory (duh)
%           the user wants to be used.   The directory is later scanned
%           to get a full list of files.
%     verbose:
%           0 or 1.  If 1, then additional messages may be printed out
%           from the command line window.
%     vslice:
%           An array of two columns of x and y data that the user wants
%           to use as an initial vslice line.
%         
nargs = length(varargin);
%for j = 1:length(varargin)
j = 1;
try
	while j < nargs
	
	    if findstr(varargin{j},'=')
	        [current_option,rest] = strtok ( varargin{j},'=' ); %#ok<NASGU>
	    else
	        current_option = varargin{j};
	    end
	
	
	    switch ( current_option ) 
	    case { 'directory' }
	        options.input_type = 'directory';
	        options.source = varargin{j+1};
	        j = j + 1;
	    case { 'file' }
	        options.input_type = 'file';
	        options.source = varargin{j+1};
	        j = j + 1;
	    case { 'nvarcutoff' }
	        options.nvarcutoff = varargin{j+1};
	        j = j + 1;
	    case { 'regexp' }
	        options.regex = varargin{j+1};
	        j = j + 1;
	    case { 'spatial' }
	        options.load_time_series_variables_only = varargin{j+1};
	        j = j + 1;
	    case { 'time_dimension' }
	        options.time_dimension = varargin{j+1};
	        j = j + 1;
	    case { 'time_variable' }
	        options.record_variable = varargin{j+1};
	        j = j + 1;
	    case 'url'
	        options.input_type = 'url';
	        options.source = varargin{j+1};
	        j = j + 1;
	    case 'variable'
	        options.default_variable = varargin{j+1};
	        j = j + 1;
	    case 'varlist'
            if iscell(varargin{j+1})
                error ( 'varlist option must be a cell array.' );
            end
	        options.restricted_varlist = varargin{j+1};
	        j = j + 1;
	    case { 'verbose' }
	        options.verbose = varargin{j+1};
	        j = j + 1;
	    case 'vslice'
            if ~strcmp(class(varargin{j+1}),'double')
                error ( 'vslice option must be numeric.' );
            end
	        options.vslice = varargin{j+1};
	        j = j + 1;
	    case 'vslice_vel'
            if ~strcmp(class(varargin{j+1}),'double')
                error ( 'vslice_vel option must be numeric.' );
            end
	        options.vslice_vel = varargin{j+1};
	        j = j + 1;
	    otherwise
	        error ( '%s:  Unhandled option %s.\n', mfilename, current_option );
	    end
	
	    j = j + 1;
	
	end
catch
    rslice_usage;
    rethrow(lasterror);
end

rslice_initialize ( hObject, options );

% -------------------------------------------------------------------------
function rslice_initialize ( hObject, options )
% RSLICE_INITIALIZE:
%
%
% gdata fields:
%     autoscale_clims:
%         If set to 1, then let matlab set the color limits for us.
%     rslice_grid:  
%         coordsys:  can be one of
%             'geographic':  datasets lon_rho, lat_rho, and angle exist
%             'xy:  datasets x_rho and y_rho exist
%
%         roms_grid:
%             As returned by call to roms_get_grid.  Useful, but this
%             doesn't give us everything we need.
%
%         x, y, angle:
%             These are structures.  If coordsys is 'geographic', then
%             x would be the structure returned from nc_getvarinfo for
%             'lon_rho'.  If coordsys is 'xy', then it is the structure
%             returned for 'x_rho'.  
%
%             If the dataset angle is not actually present in the netcdf 
%             file, then the angle field is set to the empty set.
%
%             In addition to the metadata attributes, an additional
%             field is present, 'data', which is the actual 2D 
%             array for x, y, and angle.
%
%     velocity:
%             A structure.  We have two fields
%
%             u_varinfo, v_varinfo
%  
%             These are as returned from nc_getvarinfo.
%
%     verbose:  
%         0 ==> no verbose messages
%         1 ==> verbose messages
%     input_type:
%         'file' ==>  operations are restricted to a single netcdf file
%         'directory' ==>  treat all netcdf files in said directory
%             as a single netcdf file
%     ncfile_list:
%         cell array of netcdf files (possibly just 1)
%     ncfile_index:
%         specifies the current netcdf file in "ncfile_list" being
%         operated on.
%     varname:
%         Current active variable.
%     varinfo:
%         structure of metadata pertaining to the current active
%         variable.
%     max_num_timesteps:
%         Number of timesteps in the ROMS location.  Possible contexts
%         are for all the netcdf files in a directory or just a single
%         netcdf file.
%     roms_grid:
%         As returned by call to roms_get_grid.m
%
%
% Options fields:
%    verbose:
%    location:
%    regex:
%    variable:
%        The default display variable is "h".  This option allows the
%        user to change that.
%    vslice:
%        2 column matrix.  The x coordinates 
%    

%
% CALLS:
%    roms_get_grid,
%    rslice_fix_roms_grid, rslice_io, rslice_message, 
%    rslice_set_varmenu, enable_or_disable_velocity_overlay, 
%    rslice_init_grid
% CALLED BY:
%    rslice
%

gdata = guidata ( hObject );
handles = guihandles ( hObject );

%
% set defaults.
gdata.verbose = 0;


if gdata.verbose > 0
    rslice_message ( sprintf ( '%s:  start', mfilename ) );
end



%
% Did the user specify an alternate unlimited variable?
if isfield ( options, 'record_variable' )
    gdata.record_variable = options.record_variable;
else
    gdata.record_variable = 'ocean_time';
end



%
% Did the user specify an alternate time dimension?
if isfield ( options, 'time_dimension' )
    gdata.time_dimension = options.time_dimension;
else
    gdata.time_dimension = 'ocean_time';
end




if isfield ( options, 'input_type' ) && isempty(options.input_type)
    return;
end
gdata = handleDataSource ( hObject, options, gdata );


%
% It's always the first file.
ncfile = gdata.ncfile_list{1};



gdata.rslice_grid = rslice_init_grid ( hObject, gdata );
guidata ( hObject, gdata );


%
% Start off by looking at the first file in the list (maybe there
% is only one anyway.
gdata.ncfile_index = 1;


%
% Did we specify a certain subset of variables?
% If so, this overrides the default variable.
if isfield ( options, 'restricted_varlist' )
    gdata.restricted_varlist = options.restricted_varlist;
    gdata.varname = gdata.restricted_varlist{1};
end

gdata.load_time_series_variables_only = options.load_time_series_variables_only;


%
% Set the switch for autoscaling the color limits.  Default
% is to NOT autoscale.
gdata.autoscale_clims = 0;

%
% Load information about the default variable
    if ~nc_isvar ( ncfile, gdata.varname )
        v = rslice_file_datasets ( ncfile );
        gdata.varname = v{1};
    end
gdata.varinfo = rslice_init_varinfo ( gdata, ncfile, gdata.varname );


%
% If appropriate, load in u, and v varinfo for the velocity
% slicing.
velocity_ok = get ( handles.velocity_overlay_tag, 'Enable' );
if strcmp ( velocity_ok, 'on' )
    gdata.velocity.u_varinfo = nc_getvarinfo ( ncfile, 'u' );
    gdata.velocity.v_varinfo = nc_getvarinfo ( ncfile, 'v' );
end


gdata = rslice_determine_timestep_info ( gdata );



[gdata.dim_type, gdata.z_type] = rslice_classify_variable ( gdata.varinfo );


gdata.timestep = 0;

%gdata.interpolation_method = 'nearest_neighbor';
gdata.interpolation_method = 'griddata_lite';

%
% There are certain defaults used when we draw for the first time.  We have to
% flag for this.
gdata.first_redraw = 1;


%
% Set a handle for the vslice figure.
gdata.vslice_figure = vslice;
set ( gdata.vslice_figure, 'visible', 'off' );
vdata.parent = hObject;
guidata ( gdata.vslice_figure, vdata );

%
% Set a handle for the vslice velocity figure.
gdata.vslice_vel_figure = vslice_vel;
set ( gdata.vslice_vel_figure, 'visible', 'off' );
vdata.parent = hObject;
guidata ( gdata.vslice_vel_figure, vdata );

%
% Set a handle for the horizontal velocity overlay control figure
%gdata.hvoc_figure = horizontal_velocity_overlay_controls ( hObject );
gdata.hvoc_figure = hvo;
set ( gdata.hvoc_figure, 'visible', 'off' );
hvoc_data.parent = hObject;
guidata ( gdata.hvoc_figure, hvoc_data );



%
% Now set some of the handle properties
handles = guihandles ( hObject );

set ( handles.timestep_edit, 'String', '0' );  





%
% The default is to slice on sigma level
gdata.hslice_on_sigma = 1;
switch ( gdata.dim_type )
case 'TZYX'
    gdata.max_sigma_level = gdata.varinfo.Size(2);
    gdata.sigma_index = gdata.max_sigma_level - 1;
otherwise
    gdata.sigma_index = 0;
    gdata.max_sigma_level = 0;
end


gdata.default_depth = 0.5;
switch ( gdata.dim_type )
case { 'TZYX', 'ZYX' }
    theString = sprintf ( 's=%d', gdata.sigma_index );
    set ( handles.depth_edit, 'String', theString );  
otherwise
    set ( handles.depth_edit, 'String', '' );  
end




%
% Did we specify a certain number of variables?  
if isfield ( options, 'nvarcutoff' )
    gdata.max_num_usable_vars = options.nvarcutoff;
else
    gdata.max_num_usable_vars = 20;
end





%
% store the initialized values
guidata ( hObject, gdata );

%
% setup the choice of variables.
gdata = guidata ( hObject );
rslice_set_varmenu ( hObject );

rslice_hslice_redraw ( hObject );
gdata = guidata ( hObject );

if isfield ( options, 'vslice' )

    control_pt_x = options.vslice(:,1);
    control_pt_y = options.vslice(:,2);
    vslice_data.control_pt_x = control_pt_x;
    vslice_data.control_pt_y = control_pt_y;


    %
    % Pack the gdata.vslice_data structure appropriately.
    [spx, spy] = create_vslice_line ( control_pt_x, control_pt_y );
    vslice_data.spline_x = spx;
    vslice_data.spline_y = spy;

    [hires_x, hires_y] = create_hires_line ( spx, spy );
    vslice_data.hires_x = hires_x;
    vslice_data.hires_y = hires_y;


    %
    % save the global structure again
    gdata.vslice_data = vslice_data;
    gdata.vslice_vel_data = vslice_data;
    guidata ( hObject, gdata );

    vslice_options.retrieve_new_data = 1;
    rslice_vslice_redraw ( hObject, vslice_options );

    %
    % We need to explicitly retrieve this again.
    gdata = guidata ( hObject );

end

if isfield ( options, 'vslice_vel' )

    control_pt_x = options.vslice(:,1);
    control_pt_y = options.vslice(:,2);
    vslice_data.control_pt_x = control_pt_x;
    vslice_data.control_pt_y = control_pt_y;


    %
    % Pack the gdata.vslice_data structure appropriately.
    [spx, spy] = create_vslice_line ( control_pt_x, control_pt_y );
    vslice_data.spline_x = spx;
    vslice_data.spline_y = spy;

    [hires_x, hires_y] = create_hires_line ( spx, spy );
    vslice_data.hires_x = hires_x;
    vslice_data.hires_y = hires_y;


    %
    % save the global structure again
    gdata.vslice_data = vslice_data;
    gdata.vslice_vel_data = vslice_data;
    guidata ( hObject, gdata );

    vslice_options.retrieve_new_data = 1;
    rslice_vslice_velocity_redraw ( hObject, vslice_options );

    %
    % We need to explicitly retrieve this again.
    gdata = guidata ( hObject );

end

%
% Get the default axes extents, use this for a zoom reset since 
% zoom out seems to be broken on solaris.  Jeezuz I hate solaris.
% We hates, we hates, we HATES solaris!
gdata.original_xlim = get ( handles.horizontal_slice_axis, 'XLim' );
gdata.original_ylim = get ( handles.horizontal_slice_axis, 'YLim' );

%
% store the initialized values (again)
guidata ( hObject, gdata );



return




%--------------------------------------------------------------------------
function varinfo = rslice_init_varinfo ( rslice_obj, ncfile, varname )


varinfo = [];


%
% retrieve/construct a structure of metadata for the variable in question.
%
ncfile =  rslice_obj.ncfile_list{rslice_obj.ncfile_index};
varinfo = nc_getvarinfo ( ncfile, rslice_obj.varname );


return









%--------------------------------------------------------------------------
% RSLICE_INIT_GRID:
%
% This function populates a structure called "rslice_grid".
%
%     rslice_grid:  
%         coordsys:  can be one of
%             'geographic':  datasets lon_rho, lat_rho, and angle exist
%             'xy:  datasets x_rho and y_rho exist
%
%         roms_grid:
%             As returned by call to roms_get_grid.  Useful, but this
%             doesn't give us everything we need.
%
%         x, y, angle:
%             These are structures.  If coordsys is 'geographic', then
%             x would be the structure returned from nc_getvarinfo for
%             'lon_rho'.  If coordsys is 'xy', then it is the structure
%             returned for 'x_rho'.  
%
%             If the dataset angle is not actually present in the netcdf 
%             file, then the angle field is set to the empty set.
%
%             In addition to the metadata attributes, an additional
%             field is present, 'data', which is the actual 2D 
%             array for x, y, and angle.
%
function rslice_grid = rslice_init_grid ( hObject,  gdata )

    handles = guihandles ( hObject );

%
% Classify as either 'geographic' or 'xy'
ncfile = gdata.ncfile_list{1};
if ( nc_isvar ( ncfile, 'lat_rho' ) & nc_isvar ( ncfile, 'lon_rho' ) )
    rslice_warning ( 'Classified as GEOGRAPHIC' );
    rslice_grid.coordsys = 'geographic';
elseif ( nc_isvar ( ncfile, 'x_rho' ) & nc_isvar ( ncfile, 'y_rho' )  )
    rslice_warning ( 'Classified as XY' );
    rslice_grid.coordsys = 'xy';
else
    rslice_warning ( 'Classified as IJ' );
    rslice_grid.coordsys = 'ij';
end



%
% Get what grid information we can from roms_get_grid.
ncfile = gdata.ncfile_list{1};

roms_grid = snc_roms_get_grid ( gdata.ncfile_list{1} );
roms_grid = rslice_fix_roms_grid ( gdata.ncfile_list{1}, roms_grid, rslice_grid.coordsys );
rslice_grid.roms_grid = roms_grid;



    %
    % Disable vertical slicing if we don't have the proper vertical
    % information.
    if isfield ( rslice_grid.roms_grid, 'z_r' )
        set ( handles.vslice_menu, 'Enable', 'on' );
    else
        set ( handles.vslice_menu, 'Enable', 'off' );
    end


%
% get the metadata for the x, y, and angle fields.
switch ( rslice_grid.coordsys )
case 'geographic'
    rslice_grid.x = nc_getvarinfo ( ncfile, 'lon_rho' );
    rslice_grid.y = nc_getvarinfo ( ncfile, 'lat_rho' );
    if nc_isvar ( ncfile, 'angle' )
        rslice_grid.angle = nc_getvarinfo ( ncfile, 'angle' );
    else
        rslice_grid.angle = [];
    end

case 'xy'
    x = nc_getvarinfo ( ncfile, 'x_rho' );
    y = nc_getvarinfo ( ncfile, 'y_rho' );
    
    rslice_grid.x = x;
    rslice_grid.y = y;
    rslice_grid.angle = [];

case 'ij'
    x.data = roms_grid.x_rho;
    y.data = roms_grid.y_rho;
    
    rslice_grid.x = x;
    rslice_grid.y = y;
    rslice_grid.angle = [];

        otherwise
            error ( '%s:  unhandled coordinate system %s.\n', mfilename, rslice_grid.coordsys );
end



%
% Get the actual data for x, y, and the angle.
switch ( rslice_grid.coordsys )
case 'geographic'
    rslice_grid.x.data = rslice_grid.roms_grid.lon_rho;
    rslice_grid.y.data = rslice_grid.roms_grid.lat_rho;
    if isempty(rslice_grid.angle)
        rslice_grid.have_angle = 0;
        rslice_grid.angle.data = zeros(size(rslice_grid.roms_grid.lon_rho));
    else
        rslice_grid.have_angle = 1;
        rslice_grid.angle.data = rslice_grid.roms_grid.angle;
    end

case 'xy'
    rslice_grid.x.data = nc_varget ( ncfile, 'x_rho' );
    rslice_grid.y.data = nc_varget ( ncfile, 'y_rho' );
end




%--------------------------------------------------------------------------
function gdata = handleDataSource ( hObject, options, gdata );
% handleDataSource : Check the input_type field to see whether we are dealing
% with a directory, a file, or a url.
if isfield ( options, 'input_type' )
    switch ( options.input_type )
    case 'file'
        if exist( options.source, 'file' )
            gdata.input_type = 'file';
            gdata.ncfile_list = { options.source };
        else
            msg = sprintf ( 'File %s cannot be found.\n', options.source );
            rslice_error ( msg );
        end
        gdata.varname = options.default_variable;  % default is bathymetry

    case 'directory'
        if ~exist( options.source,'dir')
            format = '%s:  Supplied directory ''%s'' does not exist.\n';
            msg = sprintf ( format, mfilename, options.source );
            rslice_error ( msg );
        end
        if ~isfield ( options , 'regex')
            format = '%s:  If you give me a directory, I also need a regular expression to narrow down the list of netcdf files.\n';
            msg = sprintf ( format, mfilename );
            rslice_error ( msg );
        end
        gdata.input_type = 'directory';
        gdata.ncfile_list = rnt_getfilenames ( options.source, options.regex, gdata );
        gdata.varname = options.default_variable;  % default is bathymetry

    case 'url'
        gdata.input_type = 'url';
        gdata.ncfile_list = { options.source };
        gdata.varname = options.default_variable;  % default is bathymetry

    otherwise
        msg = sprintf ( '%s:  unhandled input type %s.\n', mfilename, options.input_type );
    end


    %
    % At this point we need to check that we have enough information to allow for 
    % the velocity overlay
    enable_or_disable_velocity_overlay ( hObject, gdata.ncfile_list{1} );
end




% --- Outputs from this function are returned to the command line.
function varargout = rslice_OutputFcn(hObject, eventdata, handles)
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
if isfield ( handles, 'output' )
varargout{1} = handles.output;
end

return


% --- Executes during object creation, after setting all properties.
function timestep_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to timestep_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



function timestep_edit_Callback(hObject, eventdata, handles)
% hObject    handle to timestep_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of timestep_edit as text
%        str2double(get(hObject,'String')) returns contents of timestep_edit as a double


    %new_timestep = str2double ( get (handles.timestep_edit, 'String' ) );
    new_timestep_string = get (handles.timestep_edit, 'String' );
    rslice_handle_new_timestep ( hObject, eventdata, handles, new_timestep_string );
    return


% --- Executes during object creation, after setting all properties.
function depth_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to depth_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



function depth_edit_Callback(hObject, eventdata, handles)
% hObject    handle to depth_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of depth_edit as text
%        str2double(get(hObject,'String')) returns contents of depth_edit as a double


    gdata = guidata ( hObject );

    depthString = get (handles.depth_edit, 'String' );

    %
    % Try to parse it.  Is it of the form 's=%d'?  If so, then
    % it is a sigma level.  Otherwise, it must be depth.
    [s,r] = strtok ( depthString, '=' );
    if isempty(r)

        %
        % Ok, we were told to slice on depth.  Is this even possible? 
        % Check to see if we have any depth information.
        try
            if isfield ( gdata.rslice_grid.roms_grid, 'z_r' )
                %
                % We do have depth information.  Flag this fact.
                gdata.hslice_on_sigma = 0;
            else
                depthString = sprintf ( 's=%d', gdata.max_sigma_level-1 );
                set ( handles.depth_edit, 'String', depthString );
                rslice_hslice_redraw;
                return;
            end
        catch
            depthString = sprintf ( 's=%d', gdata.max_sigma_level-1 );
            set ( handles.depth_edit, 'String', depthString );
            rslice_hslice_redraw;
            return;
        end



        new_depth = str2double ( get ( handles.depth_edit, 'String' ) );

        %
        % Set the slice method

        %
        % Check to make sure that the depth is valid.  
        if isnan ( new_depth )
    
            %
            % Ok, the user did something bad.  Set the depth back to 
            % zero.
            new_depth = 0;
    
        elseif ( new_depth < -1 )
    
            %
            % Allow for a little ssh.  Actually that's quite a bit.
            new_depth = -1;
    
        end
    
        %
        % This only changes things if the value specified by the
        % user was not a valid depth.
        gdata.depth = new_depth;
        set ( handles.depth_edit, 'String', num2str(new_depth) );
    
    
    else
        [s,r] = strtok ( r, '=' );
        sigma_level = str2double ( s );
        
        %
        % If it is out of bounds, reset it.
        if sigma_level >= gdata.max_sigma_level
            sigma_level = gdata.max_sigma_level - 1;
            depthString = sprintf ( 's=%d', sigma_level );
            set ( handles.depth_edit, 'String', depthString );
        end

        %
        % Set the slice method
        gdata.sigma_index = sigma_level;
        gdata.hslice_on_sigma = 1;

    end




    %
    % Save the global data structure.
    guidata ( gcbo, gdata );


    %
    % And finally just redraw the horizontal slice at the new depth.
    rslice_hslice_redraw;



    return






% --- Executes during object creation, after setting all properties.
function horizontal_cmin_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to horizontal_cmin_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



function horizontal_cmin_edit_Callback(hObject, eventdata, handles)
% hObject    handle to horizontal_cmin_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of horizontal_cmin_edit as text
%        str2double(get(hObject,'String')) returns contents of horizontal_cmin_edit as a double


    %
    % redraw the horizontal slice with a new set of color limits.
    rslice_hslice_redraw;

    gdata = guidata ( hObject );

    %
    % Is the vslice figure visible?  If so, then issue a redraw.
    vis = get ( gdata.vslice_figure, 'Visible' );
    if strcmp ( vis, 'on' )
        rslice_vslice_redraw ( hObject );
    end

    return



% --- Executes during object creation, after setting all properties.
function horizontal_cmax_edit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to horizontal_cmax_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc
    set(hObject,'BackgroundColor','white');
else
    set(hObject,'BackgroundColor',get(0,'defaultUicontrolBackgroundColor'));
end



function horizontal_cmax_edit_Callback(hObject, eventdata, handles)
% hObject    handle to horizontal_cmax_edit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of horizontal_cmax_edit as text
%        str2double(get(hObject,'String')) returns contents of horizontal_cmax_edit as a double


    %
    % redraw the horizontal slice with a new set of color limits.
    rslice_hslice_redraw;

    gdata = guidata ( gcbo );

    %
    % Is the vslice figure visible?  If so, then issue a redraw.
    vis = get ( gdata.vslice_figure, 'Visible' );
    if strcmp ( vis, 'on' )
        rslice_vslice_redraw ( hObject );
    end

    return




% --------------------------------------------------------------------
function file_menu_Callback(hObject, eventdata, handles)
% hObject    handle to file_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function new_menu_Callback(hObject, eventdata, handles)
% hObject    handle to new_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


    %
    % Navigate to a new netcdf file.
    [filename, pathname, filterindex] = uigetfile ( '*.nc', 'Pick a ROMS File' );
    if ( filterindex == 0 )

        %
        % Ok the user canceled.  So will we.
        return

    end


    %
    % Construct the full path to the netcdf file.
    ncfile = [pathname filesep filename];

    %
    % If the file does not exist

    options = rslice_defaults;

    %
    % Do the appropriate default overrides and proceed to initialize for use.
    options.verbose = 0;
    options.input_type = 'file';
    options.source = ncfile;
    rslice_initialize ( hObject, options );

    return




% --------------------------------------------------------------------
function close_menu_Callback(hObject, eventdata, handles)
% hObject    handle to close_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    %
    % First try to delete the horizontal slice figure.
    gdata = guidata ( gcbo );
    delete ( handles.hslice_figure );

    %
    % Now try to delete the auxilliary windows.  They may or 
    % may not exist, so we have to couch this in try/catch.
    try
        delete ( gdata.vslice_vel_figure );
    end
    try
        delete ( gdata.hvoc_figure );
    end
    try
        delete ( gdata.vslice_figure );
    end
    try
        delete ( gdata.hvoc_figure );
    end

    return



% --------------------------------------------------------------------
function variable_menu_Callback(hObject, eventdata, handles)
% hObject    handle to variable_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    gdata = guidata ( gcbo );
    if ~isfield ( gdata, 'varlist' )
        fprintf ( 2, 'You need to load a dataset first.\n' );
        return
    end
    if ( length(gdata.varlist) > gdata.max_num_usable_vars)

        vml = rslice_varmenu_overflow_listbox;

        %
        % Store a reference to rslice so that the 
        % rslice_varmenu_overflow_listbox callbacks can 
        % interact with rslice again.
        vml_data = hObject;
        guidata ( vml, vml_data );

        listbox = findobj ( vml, 'Tag', 'varmenu_listbox' );
        set ( listbox, 'String', gdata.varlist );
    end
    return


% --------------------------------------------------------------------
function projection_menu_Callback(hObject, eventdata, handles)
% hObject    handle to projection_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function geographic_menu_Callback(hObject, eventdata, handles)
% hObject    handle to geographic_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function utm_menu_Callback(hObject, eventdata, handles)
% hObject    handle to utm_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function albers_equal_area_menu_Callback(hObject, eventdata, handles)
% hObject    handle to albers_equal_area_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function lambert_equal_area_azimuthal_Callback(hObject, eventdata, handles)
% hObject    handle to lambert_equal_area_azimuthal (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function other_menu_Callback(hObject, eventdata, handles)
% hObject    handle to other_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function velocity_overlay_menu_Callback(hObject, eventdata, handles)
% hObject    handle to velocity_overlay_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


    %
    % This is an old routine, can I delete it now?
    return





% --------------------------------------------------------------------
function vslice_menu_Callback(hObject, eventdata, handles)
% hObject    handle to vslice_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)



    %
    % Let the user define a new vslice line, retrieve the data
    % along that line, and render it!
    vslice_options.get_new_line = 1;
    vslice_options.retrieve_new_data = 1;
    rslice_vslice_redraw ( hObject, vslice_options );


    return



% --------------------------------------------------------------------
function zoom_menu_Callback(hObject, eventdata, handles)
% hObject    handle to zoom_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    %
    % Just make sure that 'zoom' is turned on.
    zoom ( handles.hslice_figure, 'on' );
    return


% --------------------------------------------------------------------
function Untitled_15_Callback(hObject, eventdata, handles)
% hObject    handle to Untitled_15 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --------------------------------------------------------------------
function new_directory_Callback(hObject, eventdata, handles)
% hObject    handle to new_directory (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


    pathname = uigetdir ( '.', 'Pick a ROMS Directory' );


    if isempty ( pathname )
        ncfile = pwd;
    else
        ncfile = pathname
    end

    options = rslice_defaults;


    %
    % Ask the user for a regular expression that will winnow down 
    % the list of available netcdf files.
    prompt = 'Enter a regular expression for the netcdf files.  ';
    prompt = [prompt 'See the help for rslice for details on how to use this.'] ;
    the_answer = inputdlg ( prompt );
    options.regex = the_answer{1};

    %
    % appropriately override the rest of the defaults
    options.input_type = 'directory';
    options.source = ncfile;
    options.verbose = 0;

    rslice_initialize ( hObject, options );

    return


% --------------------------------------------------------------------
function new_url_menu_Callback(hObject, eventdata, handles)
% hObject    handle to new_url_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    options = rslice_defaults;

    %
    % We can't use a fancy file diolog box for this.  
    prompt = 'Enter a new URL.' ;
    the_answer = inputdlg ( prompt );
    if isempty(the_answer)
        %
        % {} if the user hits cancel.  Do nothing.
        return
    end
    if isempty(the_answer{1})
        %
        % {} if the user hits OK with nothing in the box.  Do nothing.
        return
    end

    %
    % Do the appropriate default overrides.
    options.input_type = 'url';
    options.source = the_answer{1};

    rslice_initialize ( hObject, options );

    return


% --------------------------------------------------------------------
function zoom_back_menu_Callback(hObject, eventdata, handles)
% hObject    handle to zoom_back_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    gdata = guidata ( hObject );

    %
    % Reset the axis limits back to the original values.
    % Have to do this because "un-zoom" seems broken on
    % solaris.
    set ( handles.horizontal_slice_axis, 'XLim', gdata.original_xlim );
    set ( handles.horizontal_slice_axis, 'YLim', gdata.original_ylim );
    return


% --------------------------------------------------------------------
function velocity_overlay_tag_Callback(hObject, eventdata, handles)
% hObject    handle to velocity_overlay_tag (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    rslice_data = guidata ( hObject );

    %
    % Is the figure window still there?
    % If not, recreate it.
    try
        get ( rslice_data.hvoc_figure, 'Visible' );
    catch
        rslice_data.hvoc_figure = hvo;

        %
        % The hvoc figure needs to be able to access the rslice_data object.
        hvoc_data.parent = hObject;
        guidata ( rslice_data.hvoc_figure, hvoc_data );
    end



    rslice_velocity_overlay_redraw ( hObject );
    return



% --------------------------------------------------------------------
function vslice_velocity_menu_Callback(hObject, eventdata, handles)
% hObject    handle to vslice_velocity_menu (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    %
    % Let the user define a new vslice line, retrieve the data
    % on that line, and render it.
    vslice_options.get_new_line = 1;
    vslice_options.retrieve_new_data = 1;
    rslice_vslice_velocity_redraw ( hObject, vslice_options );


    return


% --- Executes on button press in rewind_pushbutton_back_pushbutton.
function rewind_pushbutton_back_pushbutton_Callback(hObject, eventdata, handles)
% hObject    handle to rewind_pushbutton_back_pushbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% --- Executes on button press in rewind_pushbutton_back_pushbutton.
function step_back_pushbutton_Callback(hObject, eventdata, handles)
% hObject    handle to rewind_pushbutton_back_pushbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    rslice_step_back ( hObject, handles );
    return

% --- Executes on button press in rewind_pushbutton.
function rewind_pushbutton_Callback(hObject, eventdata, handles)
% hObject    handle to rewind_pushbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    rslice_rewind ( hObject, handles );
    return

% --- Executes on button press in step_forward_pushbutton.
function step_forward_pushbutton_Callback(hObject, eventdata, handles)
% hObject    handle to step_forward_pushbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    rslice_step_forward ( hObject, handles );
    return


% --- Executes on button press in fastforward_pushbutton.
function fastforward_pushbutton_Callback(hObject, eventdata, handles)
% hObject    handle to fastforward_pushbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


    rslice_fastforward ( hObject, handles );
    return


% --- Executes on button press in stop_animation_button.
function stop_animation_button_Callback(hObject, eventdata, handles)
% hObject    handle to stop_animation_button (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    set ( handles.stop_animation_button, 'UserData', 1 );

return


% --------------------------------------------------------------------
function Print_tag_Callback(hObject, eventdata, handles)
% hObject    handle to Print_tag (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    printdlg;


% --------------------------------------------------------------------
function Toggle_clim_autoscale_Callback(hObject, eventdata, handles)
% hObject    handle to Toggle_clim_autoscale (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

    rslice_toggle_clim_autoscale ( hObject, handles );
    return



%--------------------------------------------------------------------------
function rslice_set_varmenu( arg )
% RSLICE_SET_VARMENU:  Create the menu list of variables.
%
%
% USAGE:  rslice_set_varmenu ( gcbo );
%
% PARAMETERS:
% Input:
%     gcbo:  Optional. 
%         Should be the current callback object.  This means that you
%         should be careful about calling this from the command line.
%
% If there is no "u" and "v" variables, then unset the velocity overlay
% menu
%
% Calls:
%     rslice_message
% Called By:
%


if nargin == 1
	gcbo = arg;
end
gdata = guidata ( gcbo );

if gdata.verbose > 0
	rslice_message ( sprintf ( '%s', mfilename ) );
end

handles = guihandles ( gcbo );

%
% Get rid of all the old ones
% For some reason we need to keep the last one as an empty place
% holder.  Otherwise I can't add any at all.
ch = get ( handles.variable_menu, 'Children' );
delete ( ch(1:end-1) );


netcdf_file_info = nc_info ( gdata.ncfile_list{gdata.ncfile_index} );
Dataset = netcdf_file_info.Dataset;


%
% Count the number of usable datasets
num_usable_vars = 0;
num_vars = length(Dataset );

usable_dataset = [];

first_non_grid_variable = 1;
usable_dataset = cell(num_vars,1);
for j = 1:num_vars

	% Skip certain variables.
	switch ( Dataset(j).Name )
        case { 'lon_rho', 'lat_rho', 'lon_u', 'lat_u', 'lon_v', 'lat_v' }
        	continue
	end

	%
	% If we specified a restricted list of variables from the 
	% command line, then we should ignore anything else.
	if isfield ( gdata, 'restricted_varlist' )
		did_not_find_it = 1;
		for k = 1:numel(gdata.restricted_varlist)
			if strcmp ( gdata.restricted_varlist{k}, Dataset(j).Name )
				did_not_find_it = 0;
            end
        end

		if did_not_find_it
			continue;
        end
    end

    
	dim_type = rslice_classify_variable ( Dataset(j) );
	switch ( dim_type )
    	case { 'YX', 'ZYX' }

            % Have we excluded grid variables?
            if gdata.load_time_series_variables_only
            	continue
            else

            	if first_non_grid_variable
                	gdata.default_variable = Dataset(j).Name;
                	first_non_grid_variable = 0;
                end

        		num_usable_vars = num_usable_vars + 1;
            	usable_dataset{num_usable_vars} = Dataset(j).Name;
            end

    	case { 'TZYX', 'TYX' }

        	num_usable_vars = num_usable_vars + 1;
        	usable_dataset{num_usable_vars} = Dataset(j).Name;

	end
end
usable_dataset(num_usable_vars+1:end) = [];

if isempty(usable_dataset)
	error ( '%s:  No usable datasets were found.\n', mfilename );
end
%
% Store the list of variables.
gdata.varlist = usable_dataset;

	
%
% If we only found a small number of usable datasets, then go ahead
% and put them into the Variable menu.
h = zeros(num_usable_vars,1);
if num_usable_vars < gdata.max_num_usable_vars
	for j = 1:num_usable_vars
	
		callback_string = sprintf ( 'rslice_set_new_variable( gcbo, ''%s'')', gdata.varlist{j} );
		h(j) = uimenu ( handles.variable_menu, ...
			'Callback', callback_string, ...
			'Enable', 'on', ...
			'Label', gdata.varlist{j}, ...
			'Tag', [gdata.varlist{j} '_var_menu'], ...
			'Visible', 'on' );

	end

end

%
% And save the variable list.
guidata ( gcbo, gdata );
return




%-------------------------------------------------------------------------
function rslice_handle_new_timestep ( hObject, eventdata, handles, new_timestep )
% RSLICE_HANDLE_NEW_TIMESTEP:  set a new timestep for rslice
%

gdata = guidata ( hObject );

if ischar(new_timestep)
    new_timestep = str2double(new_timestep);
end

% 
% Try to parse the input time value.  It's possible that the user gave us
% an actual index.  It's also possible that the user tried a freaking
% date string, such as '2000-03-01 15:45:17'.  Either way, we want
% an index into the ocean_time array.
%new_timestep = rslice_parse_datestring ( new_timestep, gdata.ocean_time );


%
% Check to make sure that the timestep is valid.  If not, then set it 
% to whichever extrema to which it is closest.
if isnan ( new_timestep )

	%
	% Ok, the user did something bad.  Set the timestep back to 
	% zero.
	new_timestep = 0;

elseif ( new_timestep < 0 )
	new_timestep = 0;
	gdata.timestep = 0;
elseif ( new_timestep >= gdata.max_num_timesteps )
	new_timestep = gdata.max_num_timesteps - 1;
	gdata.timestep = gdata.max_num_timesteps - 1;
else
	%
	% No fractions.
	gdata.timestep = floor(new_timestep);
end

%
% This only changes things if the value specified by the
% user was not a valid discrete timestep index.
set ( handles.timestep_edit, 'String', num2str(gdata.timestep) );

%
% If we are using a list of netcdf files, then check if we are to
% advance into another file
if strcmp ( gdata.input_type, 'directory' )
	ind = find ( (new_timestep >= gdata.ncfile_start_index) & (new_timestep <= gdata.ncfile_stop_index) );
	gdata.ncfile_index = ind;
end


guidata ( hObject, gdata );

rslice_hslice_redraw ( hObject );

%
% Is the vslice figure visible?  If so, then issue a redraw.
vis = get ( gdata.vslice_figure, 'Visible' );
if strcmp ( vis, 'on' )
	vslice_options.get_new_line = 0;
	vslice_options.retrieve_new_data = 1;
	rslice_vslice_redraw ( hObject, vslice_options );
end


%
% Is the vslice velocity figure visible?  If so, then issue a redraw.
vis = get ( gdata.vslice_vel_figure, 'Visible' );
if strcmp ( vis, 'on' )
	vslice_options.get_new_line = 0;
	vslice_options.retrieve_new_data = 1;
	rslice_vslice_velocity_redraw ( hObject, vslice_options );
end

